package jofile

import (
	"fmt"
	"os"
	"path/filepath"
	"strings"
)

func SplitFilePath(txt string) (dir, name, ext string) {
	txtLen := len(txt)

	if txtLen == 0 {
		return
	}

	idxSep := -1

	if os.PathSeparator == '/' {
		idxSep = strings.LastIndexByte(txt, os.PathSeparator)
	} else {
		idxSep = strings.LastIndexAny(txt, fmt.Sprintf("%c%c", '/', os.PathSeparator))
	}

	idxExt := strings.LastIndexByte(txt, '.')
	if idxExt > -1 {
		dir = txt[:idxSep+1]
		name = txt[idxSep+1 : idxExt]
		ext = txt[idxExt:]

		if len(name) == 0 {
			name = ext
			ext = ""
		}
	} else {
		dir = txt[:idxSep+1]
		name = txt[idxSep+1:]
		ext = ""
	}

	return
}

func FileExists(name string) bool {
	fi, err := os.Stat(name)

	if err != nil && os.IsNotExist(err) {
		return false
	}

	if fi.IsDir() {
		return false
	}

	return true
}

func FileNotExists(name string) bool {
	fi, err := os.Stat(name)
	if err != nil && os.IsNotExist(err) {
		return true
	}

	if fi.IsDir() {
		return true
	}

	return false
}

func DirExists(name string) bool {
	fi, err := os.Stat(name)

	if err != nil && os.IsNotExist(err) {
		return false
	}

	if fi.IsDir() {
		return true
	}

	return false
}

func DirNotExists(name string) bool {
	fi, err := os.Stat(name)

	if err != nil && os.IsNotExist(err) {
		return true
	}

	if fi.IsDir() {
		return false
	}

	return true
}

func CheckFilePathUpward(fileName string) (string, bool) {
	return CheckFilePathUpwardFrom(fileName, "")
}

func CheckFilePathUpwardFrom(fileName, basePath string) (string, bool) {
	if fileName == "" {
		return "", false
	}

	if strings.IndexAny(fileName, "/\\:*?\"<>|") >= 0 {
		return fmt.Sprintf("error file name '%s'", fileName), false
	}

	dirPath, err := filepath.Abs(basePath)
	if err != nil {
		return fmt.Sprintf("can not get abs path from base path '%s', error info: '%v'", basePath, err), false
	}

	fLst, err := os.ReadDir(dirPath)
	if err != nil {
		panic(fmt.Sprintf("try read directory '%s' fail, error info: %v", basePath, err))
	}

	for _, f := range fLst {
		if f.IsDir() {
			continue
		}

		if f.Name() == fileName {
			return fmt.Sprintf("%s%c%s", basePath, os.PathSeparator, f.Name()), true
		}
	}

	if dirPath == "/" {
		return "", false
	}

	tmpPath := fmt.Sprintf("%s%c..", dirPath, os.PathSeparator)
	if newPath, e := filepath.Abs(tmpPath); e != nil {
		return fmt.Sprintf("try get parent dir of '%s' fail, error info: %v", dirPath, e), false
	} else {
		if newPath == dirPath {
			// 表示已经找到根目录
			return "", false
		} else {
			return CheckFilePathUpwardFrom(fileName, newPath)
		}
	}
}
